package main

import (
	"fmt"
	"sync"
)

var wg2 sync.WaitGroup

func printNum(munOk, letterOk chan bool) {
	i := 1
	for {
		<-munOk //接收消息，接收到了就会打印，这里接收了并忽略了值
		fmt.Printf("%d%d", i, i+1)
		i += 2           //因为连续打印两个所以加2
		letterOk <- true //打印完成之后发送消息
	}
}

func printLetter(munOk, letterOk chan bool) {
	defer wg2.Done()
	//str="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	i := 65
	for i <= 90 {
		<-letterOk //接收消息，这里接收了并忽略了值
		fmt.Printf("%c%c", i, i+1)
		i += 2        //因为连续打印两个所以加2
		munOk <- true //打印完成之后发送消息
	}

}

func main() {
	/*
		交替打印数字和字母,使用两个goroutine交替打印序列，一个goroutine打印数字， 另外一个goroutine打印字母，最终效果如下：
		12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728
	*/
	var munOk chan bool = make(chan bool, 1) //声明实例化消息发生管道，用于控制通知打印
	var letterOk chan bool = make(chan bool, 1)
	wg2.Add(1)    //只添加一个监视器，由于printNum为死循环，所有通过rintLetter的结束，主程序退出
	munOk <- true //由于数字先打印，所以先给打印数字的函数发送消息
	go printNum(munOk, letterOk)
	go printLetter(munOk, letterOk)
	wg2.Wait()

	/*
		总结：只添加一个监视器，由于printNum为死循环，所有通过rintLetter的结束，主程序退出
			通过 munOk在printNum中被接收消息，能接收就会打印数字，当数字打印完成，给letterOk发送消息
				letterOk在printLetter中被接收，当能接收后就会打印字符 ，当打印完成，给munOk发消息
				主要通过两个channel的接收发送来传递谁打印，第一次自己写的没充分使用这个思路
	*/

	/*  下面为自己写的第一种 ： 没有真正用到channel的通信功能*/
	//var wg sync.WaitGroup
	//var mesg = make(chan int, 1)
	//
	//wg.Add(2)
	//go func(data chan int) {
	//	defer wg.Done()
	//	for i := 0; i <= 20; i++ {
	//		mesg <- i
	//		v := <-mesg
	//		time.Sleep(1 * time.Second)
	//		fmt.Printf("%d", v)
	//	}
	//}(mesg)
	//
	//go func(data chan int) {
	//	defer wg.Done()
	//	for i := 65; i <= 90; i++ {
	//		mesg <- i
	//		str := <-mesg
	//		time.Sleep(1 * time.Second)
	//		fmt.Printf("%c", str)
	//	}
	//}(mesg)
	//
	//wg.Wait()
}
